#include "LinkedList.h"

LinkedList::~LinkedList()
{
	ListNode *curr = head,*next;
	while(curr)
		{
			next = curr->getNext();
			delete curr;
			curr = next;
		}

}

void ListNode::insertAfter(ListNode* nd)
{
	nd->next = next;
	next = nd;
}

void ListNode::deleteAfter()
{
	if(next != NULL)
		delete(next);
}

//Linked List
void LinkedList::makeEmpty()
{
	while(head != NULL)
	{
		ListNode *tmp = (head->getNext());
		delete(head);
		head = tmp;
	}	
}

int LinkedList::isEmpty(void)
{
	if(head == NULL)
		return 1;
	return 0;
}

int LinkedList::first(ListItem& itm)
{
	if( !(isEmpty() ))
	{
		itm = head->getItem();
		return 1;
	}
	//List is empty
	return 0;
}

int LinkedList::last(ListItem& itm)
{
	if( !(isEmpty() ))
	{
		ListNode *curr = head;
		while( curr->getNext() != NULL)
			curr = curr->getNext();
		itm = curr->getItem();
	}
	//List is empty
	return 0;
}

ListNode* LinkedList::find(ListItem it)
{
	ListNode *node_to_find = head;
	while(node_to_find != NULL)
	{
		if( node_to_find->getItem() == it)
			return node_to_find;
		node_to_find = node_to_find->getNext();
	}
	return NULL;
}

ListNode* LinkedList::findPred(ListItem it)
{
	if( head->getItem() == it)
		return NULL;
	ListNode *l_node_to_find = head;
	while(l_node_to_find != NULL)
	{
		//ListItem next_itm = l_node_to_find->getNext()
		if( (l_node_to_find->getNext())->getItem() == it)
			return l_node_to_find;
		l_node_to_find = l_node_to_find->getNext();
	}
	//if nothing found
	return NULL;
}

void LinkedList::insertFirst(ListItem newItem)
{
	ListNode *l_new_item = new ListNode(newItem);
	l_new_item->setNext(head);
	head = l_new_item;
}

int LinkedList::insertAfter(ListItem it, ListItem newItem)
{
	ListNode *l_insert_after = find(it);
	if(l_insert_after == NULL)
		return 0;
	//if found
	ListNode *l_node_to_add = new ListNode(newItem);
	l_node_to_add->setNext(l_insert_after->getNext());
	l_insert_after->setNext(l_node_to_add);
	return 1;
}

void LinkedList::deleteFirst()
{
	ListNode *l_node_to_del = head;
	head = head->getNext();
	delete(l_node_to_del);
}

void LinkedList::deleteItem(ListItem it)
{
	ListNode *l_delete_after = findPred(it);
	if(l_delete_after != NULL)
	{
		ListNode *l_node_to_del = l_delete_after->getNext();
		l_delete_after->setNext(l_node_to_del->getNext());
		delete(l_node_to_del);
	}
	//NULL might also means it's the first node
	else if(head->getItem() == it)
		deleteFirst();
}

void LinkedList::print()
{
	ListNode *curr = head;
	while(curr)
	{
		cout << "[" << curr->getItem() << "]-->";
		curr = curr->getNext();
	}
	cout << "NULL" <<endl;
}

void LinkedList::reverse()
{
	ListNode *tmp, *previous = NULL,*curr=head;
	while(curr != NULL)
	{
		tmp = curr->getNext();
		curr->setNext(previous);
		previous = curr;
		curr = tmp;
	}
	head = previous;
}

